<template>
    <div v-if="!parentData || parentData.caret=='down'" style="margin-top: 16px;">
        <template v-for="(json,index) in myDataSource">
            <a-row :gutter="[0,10]" style="position:relative">
                <a-col :span="8" :style="'padding-left: '+(20*subIdx)+'px;'">
                    <a-row>
                        <a-col :span="2">
                            <a-icon v-if="json.paramType!='array' && json.caret=='down'" type="caret-down" @click="bodyDataJsonDown(json)" />
                            <a-icon v-if="json.caret=='right'" type="caret-right" @click="bodyDataJsonRight(json)" />
                        </a-col>
                      <a-col :span="2">
                        <a-tooltip :title="i18n('apiEdit.checkAll','全选')" v-if="subIdx==0">
                          <a-checkbox  @change="requireAll" style="margin-left: 8px;" />
                        </a-tooltip>
                        <a-tooltip :title="i18n('apiPreview.isRequire','是否必须')" v-else>
                          <a-checkbox v-model="json.paramRequire" :disabled="json.isChild" style="margin-left: 8px;" />
                        </a-tooltip>
                      </a-col>
                        <a-col :span="20">
                            <a-input style="width: calc(100% - 10px)" v-model="json.paramName" :disabled="json.isRoot || json.isChild"/>
                        </a-col>
                    </a-row>
                </a-col>
                <a-col :span="2">
                    <a-select style="width: calc(100% - 10px)" v-model="json.paramType" :options="paramTypeOptions" @change="paramTypeChange($event,json)" />
                </a-col>
                <template v-if="type=='return'">
                    <a-col :span="3" v-if="json.paramType!='object' && json.paramType!='array'">
                        <a-select style="width: calc(100% - 10px)" v-model="json.paramSource" :options="returnOptions" />
                    </a-col>
                    <a-col :span="3" v-else-if="returnType!='none'">
                        <a-select style="width: calc(100% - 10px)" v-model="json.paramSource" :options="[returnOptions[0],returnOptions[1]]" />
                    </a-col>
                </template>
                <template v-if="type=='body'">
                    <a-col :span="3" v-if="json.paramType!='object' && json.paramType!='array'">
                        <a-select style="width: calc(100% - 10px)" v-model="json.paramSource" :options="bodyOptions" />
                    </a-col>
                </template>

                <a-col :span="5" v-if="showParamValue(json)">
                   <div style="width: calc(100% - 10px)">
                     <a-input :placeholder="i18n('apiEdit.paramValue','参数值')" v-model="json.paramValue" v-if="json.paramSource == 'fixedVar' || json.paramSource=='jsonParse' || json.paramSource=='xmlParse'" />
                     <a-input-group v-if="json.paramSource == 'script'" compact>
                       <a-input style="width:81%;" v-model="json.paramValue" :disabled="true" />
                       <a-button @click="openScriptQuery(json)">...</a-button>
                     </a-input-group>
                     <a-select v-if="json.paramSource=='constantVar'" v-model="json.paramValue" :options="constantField"></a-select>
                   </div>
                </a-col>

                <a-col :span="spanParamDesc(json)">
                    <a-input :placeholder="i18n('apiPreview.remarks','备注')" v-model="json.paramDesc" />
                </a-col>

                <a-col :span="2">
                    <a-dropdown v-if="json.paramType=='object' && !json.isRoot && !json.isChild">
                        <a-icon type="plus-circle" class="dynamic-delete-button"/>
                        <a-menu slot="overlay">
                            <a-menu-item v-if="!json.isRoot && !json.isChild" @click="addBrotherNode(index)">{{i18n('apiEdit.addBrotherNode','添加兄弟节点')}}</a-menu-item>
                            <a-menu-item v-if="json.paramType=='object'" @click="addSonNode(json)">{{i18n('apiEdit.addChildNode','添加子节点')}}</a-menu-item>
                        </a-menu>
                    </a-dropdown>
                    <a-tooltip v-else-if="!json.isRoot && !json.isChild" :title="i18n('apiEdit.addBrotherNode','添加兄弟节点')">
                    <a-icon
                        style="margin-left: 10px;"
                        type="plus-circle"
                        class="dynamic-delete-button"
                        @click="addBrotherNode(index)"
                    />
                    </a-tooltip>
                    <a-tooltip v-else-if="json.paramType=='object'" :title="i18n('apiEdit.addChildNode','添加子节点')">
                        <a-icon
                            style="margin-left: 10px;"
                            type="plus-circle"
                            class="dynamic-delete-button"
                            @click="addSonNode(json)"
                        />
                    </a-tooltip>
                    <a-icon
                        v-if="!json.isRoot && !json.isChild"
                        class="dynamic-delete-button"
                        style="margin-left: 10px;"
                        type="minus-circle-o"
                        @click="removeNode(index)"
                    />
                </a-col>
            </a-row>
            <template v-if="json.caret=='down' && json.children && json.children.length" >
                <sys-interface-param-recursion :dataSource="json.children" :bodyDataJson="myBodyDataJson" :subIdx="subIdx+1" :parentData="json" :type="type" :apiReturnType="apiReturnType" />
            </template>
        </template>
    </div>
</template>

<script>
    import FormCustomQueryApi from '@/api/form/core/formCustomQuery'
    import {Util,Dialog} from "@lowcode/jpaas-common-lib";
    export default {
        name: "SysInterfaceParamRecursion",
        props:{
            bodyDataJson:Array,
            dataSource:Array,
            parentData:Object,
            type:String,
            apiReturnType:String,
            subIdx:{
                type:Number,
                default:0
            }
        },
        data(){
          return {
              myDataSource:this.dataSource,
              myBodyDataJson:this.bodyDataJson,
              paramTypeOptions:[
                  {label:this.i18n('apiEdit.string','字符串'),value:'string'},
                  {label:this.i18n('apiEdit.number','数字'),value:'number'},
                  {label:this.i18n('apiEdit.array','数组'),value:'array'},
                  {label:this.i18n('apiEdit.object','对象'),value:'object'},
                  {label:this.i18n('apiEdit.boolean','布尔'),value:'boolean'}
              ],
              bodyOptions:[
                  {value:"param",label:this.i18n('apiEdit.paramPassing','参数传入')},
                  {value:"fixedVar",label:this.i18n('form.fixValue','固定值')},
                  {value:"script",label:this.i18n('form.script','脚本')},
                  {value:"constantVar",label:this.i18n('form.constant','常量')}
              ],
              returnType:'none',
              returnOptions:[],
              constantField:[],
          }
        },
        mounted() {
            this.loadConstants();
            this.loadReturnOptions(this.apiReturnType);
        },
        methods:{
            i18n(name,text,key){
                return this.$ti18(name,text,"sysInterfaceProject",key);
            },
            showParamValue(json){
                if(this.type=='body'){
                    return json.paramType!='object' && json.paramType!='array' && json.paramSource!='param' && json.paramSource!='none';
                }else if(this.type=='return'){
                    return json.paramSource!='param' && json.paramSource!='none';
                }
                return false;
            },
            spanParamDesc(json){
                if(this.type=='body'){
                    return json.paramType!='object' && json.paramType!='array'?(json.paramSource!='param' && json.paramSource!='none')?4:9:12
                }else if(this.type=='return'){
                    return json.paramType!='object' && json.paramType!='array' || this.returnType!='none'?(json.paramSource!='param' && json.paramSource!='none')?4:9:12;
                }
                return 0;
            },
            loadReturnOptions(apiReturnType){
                this.returnType=apiReturnType;
                if(apiReturnType=='none'){
                    this.returnOptions=[
                        {value:"none",label:this.i18n('apiEdit.not','无')},
                        {value:"fixedVar",label:this.i18n('form.fixValue','固定值')},
                        {value:"script",label:this.i18n('form.script','脚本')},
                        {value:"constantVar",label:this.i18n('form.constant','常量')}
                    ]
                }else if(apiReturnType=='json'){
                    this.returnOptions=[
                        {value:"none",label:this.i18n('apiEdit.not','无')},
                        {value:"jsonParse",label:this.i18n('apiEdit.jsonSyntax','JSON语法')},
                        {value:"fixedVar",label:this.i18n('form.fixValue','固定值')},
                        {value:"script",label:this.i18n('form.script','脚本')},
                        {value:"constantVar",label:this.i18n('form.constant','常量')}
                    ]
                }else if(apiReturnType=='xml'){
                    this.returnOptions=[
                        {value:"none",label:this.i18n('apiEdit.not','无')},
                        {value:"xmlParse",label:this.i18n('apiEdit.xmlSyntax','XML语法')},
                        {value:"fixedVar",label:this.i18n('form.fixValue','固定值')},
                        {value:"script",label:this.i18n('form.script','脚本')},
                        {value:"constantVar",label:this.i18n('form.constant','常量')}
                    ]
                }
            },
            getNewNode(){
                return {paramName:'',caret:'',paramRequire:true,paramType:'string',paramSource:this.type=='body'?'param':'fixedVar',paramValue:'',paramDesc:'',children:[]};
            },
            addBrotherNode(index){
                //添加兄弟节点
                this.myDataSource.splice(index+1,0,this.getNewNode());
            },
            addSonNode(json){
                json.caret='down';
                //添加子节点
                json.children.push(this.getNewNode());
            },
            removeNode(index){
                //删除节点
                this.myDataSource.splice(index,1);
            },
            paramTypeChange(value,json){
                //选择类型
                json.children.length=0;
                if(value=='object'){
                    json.caret='right';
                    if(this.returnType){
                        json.paramSource=this.returnType=='json'?'jsonParse':this.returnType=='xml'?'xmlParse':'none';
                    }
                }else if(value=='array'){
                    var node=this.getNewNode();
                    json.caret='down';
                    if(this.returnType){
                        json.paramSource=this.returnType=='json'?'jsonParse':this.returnType=='xml'?'xmlParse':'none';
                    }
                    node.paramName='items';
                    node.paramRequire=false;
                    node.isChild=true;
                    json.children.push(node);
                }else{
                    json.caret='';
                }
            },
            bodyDataJsonDown(json){
                //节点收起
                json.caret='right';
            },
            bodyDataJsonRight(json){
                //节点展开
                json.caret='down';
            },
            requireAll(e){
                //必填全选
                this.setMyBodyDataJson(this.myBodyDataJson,function(item){
                    if(item.isChild){
                        return;
                    }
                    item.paramRequire=e.target.checked;
                })
            },
            setMyBodyDataJson(data,callback){
                data.forEach(item=>{
                    callback(item);
                    if(item.children && item.children.length>0){
                        this.setMyBodyDataJson(item.children,callback);
                    }
                })
            },
            loadConstants() {
                FormCustomQueryApi.getConstants().then((data) => {
                    this.constantField = this.constantField.concat(
                        data.map((item) => {
                            return { label: item.val, value: item.key }
                        })
                    )
                })
            },
            openScriptQuery(record){
                Dialog.openScripttextDialog(
                    {
                        curVm: this,
                        widthHeight: ['800px', '600px'],
                        data: { script: record.paramValue },
                    },
                    function (self, data) {
                        record.paramValue = data
                    }
                )
            },
        },
        watch:{
            apiReturnType:{
                handler:function(val){
                    this.loadReturnOptions(val);
                    this.myDataSource=this.myDataSource.map(item=>{
                        if(val=='json'){
                            item.paramSource=item.paramSource=='xmlParse'?'jsonParse':item.paramSource;
                        }else if(val=='xml'){
                            item.paramSource=item.paramSource=='jsonParse'?'xmlParse':item.paramSource;
                        }else{
                            item.paramSource=item.paramSource=='xmlParse' || item.paramSource=='jsonParse'?'none':item.paramSource;
                        }
                        return item;
                    })
                }
            },
            dataSource:{
                handler:function (val,odlval) {
                    this.myDataSource = val;
                },
                deep:true
            },
            bodyDataJson:{
                handler:function (val,odlval) {
                    this.myBodyDataJson = val;
                },
                deep:true
            }
        }
    }
</script>

<style scoped>

</style>